package model.skill;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import model.effect.ConstantChangeStatEffect;
import model.effect.Effect;
import model.effect.SleepEffect;
import model.entity.stats.StatType;
import model.interactionhandler.InteractionContainer;
import model.item.EquippableItem;
import model.map.Direction;
import model.map.HexLocationProjection;
import model.map.Location;
import model.map.LocationProjection;
import utilities.*;

public class ProjectileLibrary implements Archiveable {
	
	static private ProjectileLibrary instance = null;
	
	private static Map<String, LinearProjectile> linearProjectileMap;
	private static Map<String, AngularProjectile> angularProjectileMap;
	private static Map<String, RadialProjectile> radialProjectileMap;
	private static Map<String, SelfProjectile> selfProjectileMap;

	private ProjectileLibrary()
	{
		linearProjectileMap = new HashMap<String, LinearProjectile>();
		angularProjectileMap = new HashMap<String, AngularProjectile>();
		radialProjectileMap = new HashMap<String, RadialProjectile>();
		selfProjectileMap = new HashMap<String, SelfProjectile>();
		initLibrary();
	}
	
	public static ProjectileLibrary getInstance() {
		if ( instance != null ) {
			return instance;
		}
		return instance = new ProjectileLibrary();
	}
	
	private void initLibrary()
	{
		//String name, Effect effect, LocationProjection propagationLogic, int range, int speed
		LocationProjection hex = new HexLocationProjection(); 
		
		int fastSpeed = 10;
		int mediumSpeed = 35;
		int slowSpeed = 50;
		
		int longDistance = 9;
		int mediumDistance = 6;
		int shortDistance = 3;
		
		Effect heavyHealthDamage = new ConstantChangeStatEffect("HeavyHealthDamage", StatType.HP, -100);
		Effect mediumHealthDamage = new ConstantChangeStatEffect("MediumHealthDamage", StatType.HP, -50);
		Effect lightHealthDamage = new ConstantChangeStatEffect("LightHealthDamage", StatType.HP, -10);
		Effect baneEffect = new ConstantChangeStatEffect("BaneEffect", StatType.HP, -20);
		Effect healDamage = new ConstantChangeStatEffect("HealDamage", StatType.HP, 10);
		Effect beerHealEffect = new ConstantChangeStatEffect("HealDamage", StatType.HP, 50);
		SleepEffect sleepEffect = new SleepEffect("SleepEffect", 10);
		Effect handedDamage = new ConstantChangeStatEffect("SwordDamage", StatType.HP, 30);
		Effect twoHandedDamage = new ConstantChangeStatEffect("SwordDamage", StatType.HP, 50);
		Effect brawlDamage = new ConstantChangeStatEffect("HandDamage", StatType.HP, 10);
		Effect staffDamage = new ConstantChangeStatEffect("HandDamage", StatType.HP, 10);
		Effect rangeDamage = new ConstantChangeStatEffect("HandDamage", StatType.HP, 50);
		
		LinearProjectile linearProjectileSlowSpeedAndHeavyDamageAndLongDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, longDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndHeavyDamageAndMediumDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, mediumDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndHeavyDamageAndShortDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, shortDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndMediumDamageAndLongDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, longDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndMediumDamageAndMediumDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, mediumDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndMediumDamageAndShortDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, shortDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndLightDamageAndLongDistance= new LinearProjectile("projectile", lightHealthDamage, hex, longDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndLightDamageAndMediumDistance= new LinearProjectile("projectile", lightHealthDamage, hex, mediumDistance, slowSpeed);
		LinearProjectile linearProjectileSlowSpeedAndLightDamageAndShortDistance= new LinearProjectile("projectile", lightHealthDamage, hex, shortDistance, slowSpeed);

		LinearProjectile linearProjectileMediumSpeedAndHeavyDamageAndLongDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, longDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndHeavyDamageAndMediumDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, mediumDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndHeavyDamageAndShortDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, shortDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndMediumDamageAndLongDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, longDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndMediumDamageAndMediumDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, mediumDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndMediumDamageAndShortDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, shortDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndLightDamageAndLongDistance= new LinearProjectile("projectile", lightHealthDamage, hex, longDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndLightDamageAndMediumDistance= new LinearProjectile("projectile", lightHealthDamage, hex, mediumDistance, mediumSpeed);
		LinearProjectile linearProjectileMediumSpeedAndLightDamageAndShortDistance= new LinearProjectile("projectile", lightHealthDamage, hex, shortDistance, mediumSpeed);

		LinearProjectile linearProjectileFastSpeedAndHeavyDamageAndLongDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, longDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndHeavyDamageAndMediumDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, mediumDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndHeavyDamageAndShortDistance= new LinearProjectile("projectile", heavyHealthDamage, hex, shortDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndMediumDamageAndLongDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, longDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndMediumDamageAndMediumDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, mediumDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndMediumDamageAndShortDistance= new LinearProjectile("projectile", mediumHealthDamage, hex, shortDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndLightDamageAndLongDistance= new LinearProjectile("projectile", lightHealthDamage, hex, longDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndLightDamageAndMediumDistance= new LinearProjectile("projectile", lightHealthDamage, hex, mediumDistance, fastSpeed);
		LinearProjectile linearProjectileFastSpeedAndLightDamageAndShortDistance= new LinearProjectile("projectile", lightHealthDamage, hex, shortDistance, fastSpeed);

		AngularProjectile angularProjectileSlowSpeedAndHeavyDamageAndLongDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, longDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndHeavyDamageAndMediumDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, mediumDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndHeavyDamageAndShortDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, shortDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndMediumDamageAndLongDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, longDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndMediumDamageAndMediumDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, mediumDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndMediumDamageAndShortDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, shortDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndLightDamageAndLongDistance= new AngularProjectile("projectile", lightHealthDamage, hex, longDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndLightDamageAndMediumDistance= new AngularProjectile("projectile", lightHealthDamage, hex, mediumDistance, slowSpeed);
		AngularProjectile angularProjectileSlowSpeedAndLightDamageAndShortDistance= new AngularProjectile("projectile", lightHealthDamage, hex, shortDistance, slowSpeed);

		AngularProjectile angularProjectileMediumSpeedAndHeavyDamageAndLongDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, longDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndHeavyDamageAndMediumDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, mediumDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndHeavyDamageAndShortDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, shortDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndMediumDamageAndLongDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, longDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndMediumDamageAndMediumDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, mediumDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndMediumDamageAndShortDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, shortDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndLightDamageAndLongDistance= new AngularProjectile("projectile", lightHealthDamage, hex, longDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndLightDamageAndMediumDistance= new AngularProjectile("projectile", lightHealthDamage, hex, mediumDistance, mediumSpeed);
		AngularProjectile angularProjectileMediumSpeedAndLightDamageAndShortDistance= new AngularProjectile("projectile", lightHealthDamage, hex, shortDistance, mediumSpeed);

		AngularProjectile angularProjectileFastSpeedAndHeavyDamageAndLongDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, longDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndHeavyDamageAndMediumDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, mediumDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndHeavyDamageAndShortDistance= new AngularProjectile("projectile", heavyHealthDamage, hex, shortDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndMediumDamageAndLongDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, longDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndMediumDamageAndMediumDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, mediumDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndMediumDamageAndShortDistance= new AngularProjectile("projectile", mediumHealthDamage, hex, shortDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndLightDamageAndLongDistance= new AngularProjectile("projectile", lightHealthDamage, hex, longDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndLightDamageAndMediumDistance= new AngularProjectile("projectile", lightHealthDamage, hex, mediumDistance, fastSpeed);
		AngularProjectile angularProjectileFastSpeedAndLightDamageAndShortDistance= new AngularProjectile("projectile", lightHealthDamage, hex, shortDistance, fastSpeed);

		RadialProjectile radialProjectileSlowSpeedAndHeavyDamageAndLongDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, longDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndHeavyDamageAndMediumDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, mediumDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndHeavyDamageAndShortDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, shortDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndMediumDamageAndLongDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, longDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndMediumDamageAndMediumDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, mediumDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndMediumDamageAndShortDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, shortDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndLightDamageAndLongDistance= new RadialProjectile("projectile", lightHealthDamage, hex, longDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndLightDamageAndMediumDistance= new RadialProjectile("projectile", lightHealthDamage, hex, mediumDistance, slowSpeed);
		RadialProjectile radialProjectileSlowSpeedAndLightDamageAndShortDistance= new RadialProjectile("projectile", lightHealthDamage, hex, shortDistance, slowSpeed);

		RadialProjectile radialProjectileMediumSpeedAndHeavyDamageAndLongDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, longDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndHeavyDamageAndMediumDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, mediumDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndHeavyDamageAndShortDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, shortDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndMediumDamageAndLongDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, longDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndMediumDamageAndMediumDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, mediumDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndMediumDamageAndShortDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, shortDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndLightDamageAndLongDistance= new RadialProjectile("projectile", lightHealthDamage, hex, longDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndLightDamageAndMediumDistance= new RadialProjectile("projectile", lightHealthDamage, hex, mediumDistance, mediumSpeed);
		RadialProjectile radialProjectileMediumSpeedAndLightDamageAndShortDistance= new RadialProjectile("projectile", lightHealthDamage, hex, shortDistance, mediumSpeed);

		RadialProjectile radialProjectileFastSpeedAndHeavyDamageAndLongDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, longDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndHeavyDamageAndMediumDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, mediumDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndHeavyDamageAndShortDistance= new RadialProjectile("projectile", heavyHealthDamage, hex, shortDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndMediumDamageAndLongDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, longDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndMediumDamageAndMediumDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, mediumDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndMediumDamageAndShortDistance= new RadialProjectile("projectile", mediumHealthDamage, hex, shortDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndLightDamageAndLongDistance= new RadialProjectile("projectile", lightHealthDamage, hex, longDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndLightDamageAndMediumDistance= new RadialProjectile("projectile", lightHealthDamage, hex, mediumDistance, fastSpeed);
		RadialProjectile radialProjectileFastSpeedAndLightDamageAndShortDistance= new RadialProjectile("projectile", lightHealthDamage, hex, shortDistance, fastSpeed);
		
		SelfProjectile selfProjectileFastSpeedAndHeavyDamage = new SelfProjectile("projectile", heavyHealthDamage, hex, fastSpeed);
		SelfProjectile selfProjectileFastSpeedAndMediumDamage = new SelfProjectile("projectile", mediumHealthDamage, hex, fastSpeed);
		SelfProjectile selfProjectileFastSpeedAndLightDamage = new SelfProjectile("projectile", lightHealthDamage, hex, fastSpeed);
		SelfProjectile selfProjectileMediumSpeedAndHeavyDamage = new SelfProjectile("projectile", heavyHealthDamage, hex, mediumSpeed);
		SelfProjectile selfProjectileMediumSpeedAndMediumDamage = new SelfProjectile("projectile", mediumHealthDamage, hex, mediumSpeed);
		SelfProjectile selfProjectileMediumSpeedAndLightDamage = new SelfProjectile("projectile", lightHealthDamage, hex, mediumSpeed);
		SelfProjectile selfProjectileSlowSpeedAndHeavyDamage = new SelfProjectile("projectile", heavyHealthDamage, hex, slowSpeed);
		SelfProjectile selfProjectileSlowSpeedAndMediumDamage = new SelfProjectile("projectile", mediumHealthDamage, hex, slowSpeed);
		SelfProjectile selfProjectileSlowSpeedAndLightDamage = new SelfProjectile("projectile", lightHealthDamage, hex, slowSpeed);
		
		SelfProjectile selfProjectileHealDamage = new SelfProjectile("projectile", healDamage, hex, slowSpeed);
		SelfProjectile selfProjectileSleepEffect = new SelfProjectile("projectile", sleepEffect, hex, slowSpeed);
		SelfProjectile selfProjectileBaneEffect = new SelfProjectile("projectile", baneEffect, hex, slowSpeed);
		SelfProjectile selfProjectileBeerEffect = new SelfProjectile("projectile", beerHealEffect, hex, slowSpeed);
		
		LinearProjectile linearSwordAttack= new LinearProjectile("projectile", handedDamage, hex, 1, mediumSpeed);
		LinearProjectile linearTwoSwordAttack= new LinearProjectile("projectile", twoHandedDamage, hex, 1, slowSpeed);
		LinearProjectile brawlAttack = new LinearProjectile("projectile", brawlDamage, hex, 1, fastSpeed);
		LinearProjectile staffAttack = new LinearProjectile("projectile", staffDamage, hex, 1, fastSpeed);
		LinearProjectile rangeAttack = new LinearProjectile("projectile", rangeDamage, hex, 1, fastSpeed);

		
		
		linearProjectileMap.put("linearProjectileSlowSpeedAndHeavyDamageAndLongDistance", linearProjectileSlowSpeedAndHeavyDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndHeavyDamageAndMediumDistance", linearProjectileSlowSpeedAndHeavyDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndHeavyDamageAndShortDistance", linearProjectileSlowSpeedAndHeavyDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndMediumDamageAndLongDistance", linearProjectileSlowSpeedAndMediumDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndMediumDamageAndMediumDistance", linearProjectileSlowSpeedAndMediumDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndMediumDamageAndShortDistance", linearProjectileSlowSpeedAndMediumDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndLightDamageAndLongDistance", linearProjectileSlowSpeedAndLightDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndLightDamageAndMediumDistance", linearProjectileSlowSpeedAndLightDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileSlowSpeedAndLightDamageAndShortDistance", linearProjectileSlowSpeedAndLightDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndHeavyDamageAndLongDistance", linearProjectileMediumSpeedAndHeavyDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndHeavyDamageAndMediumDistance", linearProjectileMediumSpeedAndHeavyDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndHeavyDamageAndShortDistance", linearProjectileMediumSpeedAndHeavyDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndMediumDamageAndLongDistance", linearProjectileMediumSpeedAndMediumDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndMediumDamageAndMediumDistance", linearProjectileMediumSpeedAndMediumDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndMediumDamageAndShortDistance", linearProjectileMediumSpeedAndMediumDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndLightDamageAndLongDistance", linearProjectileMediumSpeedAndLightDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndLightDamageAndMediumDistance", linearProjectileMediumSpeedAndLightDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileMediumSpeedAndLightDamageAndShortDistance", linearProjectileMediumSpeedAndLightDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndHeavyDamageAndLongDistance", linearProjectileFastSpeedAndHeavyDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndHeavyDamageAndMediumDistance", linearProjectileFastSpeedAndHeavyDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndHeavyDamageAndShortDistance", linearProjectileFastSpeedAndHeavyDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndMediumDamageAndLongDistance", linearProjectileFastSpeedAndMediumDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndMediumDamageAndMediumDistance", linearProjectileFastSpeedAndMediumDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndMediumDamageAndShortDistance", linearProjectileFastSpeedAndMediumDamageAndShortDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndLightDamageAndLongDistance", linearProjectileFastSpeedAndLightDamageAndLongDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndLightDamageAndMediumDistance", linearProjectileFastSpeedAndLightDamageAndMediumDistance);
		linearProjectileMap.put("linearProjectileFastSpeedAndLightDamageAndShortDistance", linearProjectileFastSpeedAndLightDamageAndShortDistance);
		linearProjectileMap.put("linearSwordAttack", linearSwordAttack);
		linearProjectileMap.put("linearTwoSwordAttack", linearTwoSwordAttack);
		linearProjectileMap.put("brawlAttack", brawlAttack);
		linearProjectileMap.put("staffAttack", staffAttack);
		linearProjectileMap.put("rangeAttack", rangeAttack);

		angularProjectileMap.put("angularProjectileSlowSpeedAndHeavyDamageAndLongDistance", angularProjectileSlowSpeedAndHeavyDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndHeavyDamageAndMediumDistance", angularProjectileSlowSpeedAndHeavyDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndHeavyDamageAndShortDistance", angularProjectileSlowSpeedAndHeavyDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndMediumDamageAndLongDistance", angularProjectileSlowSpeedAndMediumDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndMediumDamageAndMediumDistance", angularProjectileSlowSpeedAndMediumDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndMediumDamageAndShortDistance", angularProjectileSlowSpeedAndMediumDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndLightDamageAndLongDistance", angularProjectileSlowSpeedAndLightDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndLightDamageAndMediumDistance", angularProjectileSlowSpeedAndLightDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileSlowSpeedAndLightDamageAndShortDistance", angularProjectileSlowSpeedAndLightDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndHeavyDamageAndLongDistance", angularProjectileMediumSpeedAndHeavyDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndHeavyDamageAndMediumDistance", angularProjectileMediumSpeedAndHeavyDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndHeavyDamageAndShortDistance", angularProjectileMediumSpeedAndHeavyDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndMediumDamageAndLongDistance", angularProjectileMediumSpeedAndMediumDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndMediumDamageAndMediumDistance", angularProjectileMediumSpeedAndMediumDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndMediumDamageAndShortDistance", angularProjectileMediumSpeedAndMediumDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndLightDamageAndLongDistance", angularProjectileMediumSpeedAndLightDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndLightDamageAndMediumDistance", angularProjectileMediumSpeedAndLightDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileMediumSpeedAndLightDamageAndShortDistance", angularProjectileMediumSpeedAndLightDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndHeavyDamageAndLongDistance", angularProjectileFastSpeedAndHeavyDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndHeavyDamageAndMediumDistance", angularProjectileFastSpeedAndHeavyDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndHeavyDamageAndShortDistance", angularProjectileFastSpeedAndHeavyDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndMediumDamageAndLongDistance", angularProjectileFastSpeedAndMediumDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndMediumDamageAndMediumDistance", angularProjectileFastSpeedAndMediumDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndMediumDamageAndShortDistance", angularProjectileFastSpeedAndMediumDamageAndShortDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndLightDamageAndLongDistance", angularProjectileFastSpeedAndLightDamageAndLongDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndLightDamageAndMediumDistance", angularProjectileFastSpeedAndLightDamageAndMediumDistance);
		angularProjectileMap.put("angularProjectileFastSpeedAndLightDamageAndShortDistance", angularProjectileFastSpeedAndLightDamageAndShortDistance);

		radialProjectileMap.put("radialProjectileSlowSpeedAndHeavyDamageAndLongDistance", radialProjectileSlowSpeedAndHeavyDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndHeavyDamageAndMediumDistance", radialProjectileSlowSpeedAndHeavyDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndHeavyDamageAndShortDistance", radialProjectileSlowSpeedAndHeavyDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndMediumDamageAndLongDistance", radialProjectileSlowSpeedAndMediumDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndMediumDamageAndMediumDistance", radialProjectileSlowSpeedAndMediumDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndMediumDamageAndShortDistance", radialProjectileSlowSpeedAndMediumDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndLightDamageAndLongDistance", radialProjectileSlowSpeedAndLightDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndLightDamageAndMediumDistance", radialProjectileSlowSpeedAndLightDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileSlowSpeedAndLightDamageAndShortDistance", radialProjectileSlowSpeedAndLightDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndHeavyDamageAndLongDistance", radialProjectileMediumSpeedAndHeavyDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndHeavyDamageAndMediumDistance", radialProjectileMediumSpeedAndHeavyDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndHeavyDamageAndShortDistance", radialProjectileMediumSpeedAndHeavyDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndMediumDamageAndLongDistance", radialProjectileMediumSpeedAndMediumDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndMediumDamageAndMediumDistance", radialProjectileMediumSpeedAndMediumDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndMediumDamageAndShortDistance", radialProjectileMediumSpeedAndMediumDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndLightDamageAndLongDistance", radialProjectileMediumSpeedAndLightDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndLightDamageAndMediumDistance", radialProjectileMediumSpeedAndLightDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileMediumSpeedAndLightDamageAndShortDistance", radialProjectileMediumSpeedAndLightDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndHeavyDamageAndLongDistance", radialProjectileFastSpeedAndHeavyDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndHeavyDamageAndMediumDistance", radialProjectileFastSpeedAndHeavyDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndHeavyDamageAndShortDistance", radialProjectileFastSpeedAndHeavyDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndMediumDamageAndLongDistance", radialProjectileFastSpeedAndMediumDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndMediumDamageAndMediumDistance", radialProjectileFastSpeedAndMediumDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndMediumDamageAndShortDistance", radialProjectileFastSpeedAndMediumDamageAndShortDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndLightDamageAndLongDistance", radialProjectileFastSpeedAndLightDamageAndLongDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndLightDamageAndMediumDistance", radialProjectileFastSpeedAndLightDamageAndMediumDistance);
		radialProjectileMap.put("radialProjectileFastSpeedAndLightDamageAndShortDistance", radialProjectileFastSpeedAndLightDamageAndShortDistance);

		selfProjectileMap.put("selfProjectileFastSpeedAndHeavyDamage", selfProjectileFastSpeedAndHeavyDamage);
		selfProjectileMap.put("selfProjectileFastSpeedAndMediumDamage", selfProjectileFastSpeedAndMediumDamage);
		selfProjectileMap.put("selfProjectileFastSpeedAndLightDamage", selfProjectileFastSpeedAndLightDamage);
		selfProjectileMap.put("selfProjectileMediumSpeedAndHeavyDamage", selfProjectileMediumSpeedAndHeavyDamage);
		selfProjectileMap.put("selfProjectileMediumSpeedAndMediumDamage", selfProjectileMediumSpeedAndMediumDamage);
		selfProjectileMap.put("selfProjectileMediumSpeedAndLightDamage", selfProjectileMediumSpeedAndLightDamage);
		selfProjectileMap.put("selfProjectileSlowSpeedAndHeavyDamage", selfProjectileSlowSpeedAndHeavyDamage);
		selfProjectileMap.put("selfProjectileSlowSpeedAndMediumDamage", selfProjectileSlowSpeedAndMediumDamage);
		selfProjectileMap.put("selfProjectileSlowSpeedAndLightDamage", selfProjectileSlowSpeedAndLightDamage);
		selfProjectileMap.put("selfProjectileHealDamage", selfProjectileHealDamage);
		selfProjectileMap.put("selfProjectileSleepEffect", selfProjectileSleepEffect);
		selfProjectileMap.put("selfProjectileBaneEffect", selfProjectileBaneEffect);
		selfProjectileMap.put("selfProjectileBeerEffect", selfProjectileBeerEffect);
		
	}
	
	public static LinearProjectile getLinearProjectile(String name)
	{
		return linearProjectileMap.get(name);
	}
	
	public static AngularProjectile getAngularProjectile(String name)
	{
		return angularProjectileMap.get(name);
	}
	
	public static RadialProjectile getRadialProjectile(String name)
	{
		return radialProjectileMap.get(name);
	}
	
	public static SelfProjectile getSelfProjectile(String name)
	{
		return selfProjectileMap.get(name);
	}
	
	public Archive save() {
		Archive archive = ArchiveFactory.createArchive();
		
		List<String> angularProjectileMapClassList = new ArrayList<String>();
		List<String> angularProjectileMapKeys = new ArrayList<String>(angularProjectileMap.keySet());
		List<AngularProjectile> angularProjectileMapValues = new ArrayList<AngularProjectile>();
		for (int i = 0; i < angularProjectileMapKeys.size(); i++) {
			String key = angularProjectileMapKeys.get(i);
			AngularProjectile item = angularProjectileMap.get(key);
			angularProjectileMapClassList.add(item.getClass().getName());
			angularProjectileMapValues.add(item);
		}
		archive.putAttributeList("angularProjectileMapClassList", angularProjectileMapClassList);
		archive.putAttributeList("angularProjectileMapKeys", angularProjectileMapKeys);
		archive.putManyRelationship("angularProjectileMapValues", angularProjectileMapValues);
		
		
		List<String> linearProjectileMapClassList = new ArrayList<String>();
		List<String> linearProjectileMapKeys = new ArrayList<String>(linearProjectileMap.keySet());
		List<LinearProjectile> linearProjectileMapValues = new ArrayList<LinearProjectile>();
		for (int i = 0; i < linearProjectileMapKeys.size(); i++) {
			String key = linearProjectileMapKeys.get(i);
			LinearProjectile item = linearProjectileMap.get(key);
			linearProjectileMapClassList.add(item.getClass().getName());
			linearProjectileMapValues.add(item);
		}
		archive.putAttributeList("linearProjectileMapClassList", linearProjectileMapClassList);
		archive.putAttributeList("linearProjectileMapKeys", linearProjectileMapKeys);
		archive.putManyRelationship("linearProjectileMapValues", linearProjectileMapValues);
		
		
		List<String> radialProjectileMapClassList = new ArrayList<String>();
		List<String> radialProjectileMapKeys = new ArrayList<String>(radialProjectileMap.keySet());
		List<RadialProjectile> radialProjectileMapValues = new ArrayList<RadialProjectile>();
		for (int i = 0; i < angularProjectileMapKeys.size(); i++) {
			String key = angularProjectileMapKeys.get(i);
			RadialProjectile item = radialProjectileMap.get(key);
			radialProjectileMapClassList.add(item.getClass().getName());
			radialProjectileMapValues.add(item);
		}
		archive.putAttributeList("radialProjectileMapClassList", radialProjectileMapClassList);
		archive.putAttributeList("radialProjectileMapKeys", radialProjectileMapKeys);
		archive.putManyRelationship("radialProjectileMapValues", radialProjectileMapValues);
		
		
		List<String> selfProjectileMapClassList = new ArrayList<String>();
		List<String> selfProjectileMapKeys = new ArrayList<String>(selfProjectileMap.keySet());
		List<SelfProjectile> selfProjectileMapValues = new ArrayList<SelfProjectile>();
		for (int i = 0; i < selfProjectileMapKeys.size(); i++) {
			String key = selfProjectileMapKeys.get(i);
			SelfProjectile item = selfProjectileMap.get(key);
			selfProjectileMapClassList.add(item.getClass().getName());
			selfProjectileMapValues.add(item);
		}
		archive.putAttributeList("selfProjectileMapClassList", selfProjectileMapClassList);
		archive.putAttributeList("selfProjectileMapKeys", selfProjectileMapKeys);
		archive.putManyRelationship("selfProjectileMapValues", selfProjectileMapValues);
		
		
		return archive;
	}
	
	public void load(Archive archive) {
		List<String> angularProjectileMapClassList = archive.getAttributeList("angularProjectileMapClassList");
		List<String> angularProjectileMapKeys = archive.getAttributeList("angularProjectileMapKeys");
		List<Archive> angularProjectileMapValues = archive.getManyRelationship("angularProjectileMapValues");
		angularProjectileMap = new HashMap<String, AngularProjectile>();
		for (int i = 0; i < angularProjectileMapClassList.size(); i++) {
			String key = angularProjectileMapKeys.get(i);
			String className = angularProjectileMapClassList.get(i);
			AngularProjectile projectile = (AngularProjectile)ModelFactory.getInstance().createInstanceWithClassName(className);
			projectile.load(angularProjectileMapValues.get(i));
			angularProjectileMap.put(key, projectile);
		}
		
		
		List<String> linearProjectileMapClassList = archive.getAttributeList("linearProjectileMapClassList");
		List<String> linearProjectileMapKeys = archive.getAttributeList("linearProjectileMapKeys");
		List<Archive> linearProjectileMapValues = archive.getManyRelationship("linearProjectileMapValues");
		linearProjectileMap = new HashMap<String, LinearProjectile>();
		for (int i = 0; i < linearProjectileMapClassList.size(); i++) {
			String key = linearProjectileMapKeys.get(i);
			String className = linearProjectileMapClassList.get(i);
			LinearProjectile projectile = (LinearProjectile)ModelFactory.getInstance().createInstanceWithClassName(className);
			projectile.load(linearProjectileMapValues.get(i));
			linearProjectileMap.put(key, projectile);
		}
		
		
		List<String> radialProjectileMapClassList = archive.getAttributeList("radialProjectileMapClassList");
		List<String> radialProjectileMapKeys = archive.getAttributeList("radialProjectileMapKeys");
		List<Archive> radialProjectileMapValues = archive.getManyRelationship("radialProjectileMapValues");
		radialProjectileMap = new HashMap<String, RadialProjectile>();
		for (int i = 0; i < radialProjectileMapClassList.size(); i++) {
			String key = radialProjectileMapKeys.get(i);
			String className = radialProjectileMapClassList.get(i);
			RadialProjectile projectile = (RadialProjectile)ModelFactory.getInstance().createInstanceWithClassName(className);
			projectile.load(radialProjectileMapValues.get(i));
			radialProjectileMap.put(key, projectile);
		}
		
		
		List<String> selfProjectileMapClassList = archive.getAttributeList("selfProjectileMapClassList");
		List<String> selfProjectileMapKeys = archive.getAttributeList("selfProjectileMapKeys");
		List<Archive> selfProjectileMapValues = archive.getManyRelationship("selfProjectileMapValues");
		selfProjectileMap = new HashMap<String, SelfProjectile>();
		for (int i = 0; i < selfProjectileMapClassList.size(); i++) {
			String key = selfProjectileMapKeys.get(i);
			String className = selfProjectileMapClassList.get(i);
			SelfProjectile projectile = (SelfProjectile)ModelFactory.getInstance().createInstanceWithClassName(className);
			projectile.load(selfProjectileMapValues.get(i));
			selfProjectileMap.put(key, projectile);
		}
		
	}
}
